package com.tduck.cloud.api.web.ao;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.sun.jndi.rmi.registry.ReferenceWrapper_Stub;
import com.tduck.cloud.account.entity.OrgEntity;
import com.tduck.cloud.account.entity.UserEntity;
import com.tduck.cloud.account.service.OrgService;
import com.tduck.cloud.account.service.UserService;
import com.tduck.cloud.common.util.RedisUtil;
import com.tduck.cloud.form.entity.FormUserRelationEntity;
import com.tduck.cloud.form.entity.RelationshipEntity;
import com.tduck.cloud.form.entity.RelationshipExportVO;
import com.tduck.cloud.form.entity.enums.FormTypeEnum;
import com.tduck.cloud.form.service.FormUserRelationService;
import com.tduck.cloud.form.service.RelationshipService;
import com.tduck.cloud.form.service.UserFormService;
import com.tencentcloudapi.cms.v20190321.models.ImageTerrorDetect;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 评价关系业务
 *
 * @author Guard Baby
 * @date 2023/05/24
 */
@Slf4j
@Service("relationshipAO")
@RequiredArgsConstructor
public class RelationshipAO {
    private final OrgService orgService;
    private final UserService userService;
    private final RelationshipService relationshipService;
    private final RedisUtil redisUtil;
    private final FormUserRelationService formUserRelationService;

    private static final String IMPORT_ORG_KEY = "relationship:org:";
    private static final String IMPORT_PERSON_KEY = "relationship:person:%s:%s";
    private static final Long EXPIRED_TIME = 60 * 60 * 10L;


    @Transactional(rollbackFor = Exception.class)
    public String importData(InputStream inputStream, String formKey, Integer formType) {
        StringBuilder stringBuilder = new StringBuilder();
        List<RelationshipEntity> relationshipEntityList = Lists.newArrayList();
        ExcelReader reader = ExcelUtil.getReader(inputStream);
        List<List<Object>> readAll = reader.read();
        // 标题行
//        List<Object> headRow = readAll.get(0);
        int evaluatedNameRowNum = 0;
        int evaluatorNameRowNum = 1;
        int evaluatorCodeRowNum = 2;
        int evaluatedCodeRowNum = 0;

        if (FormTypeEnum.PERSON.getValue().equals(formType)) {
            evaluatedNameRowNum = 1;
            evaluatorNameRowNum = 3;
        }
        List<Map<String, Object>> rows = CollUtil.newArrayList();
        for (int i = 1; i < readAll.size(); i++) {
            List<Object> row = readAll.get(i);
            String evaluatedCode = CollUtil.get(row, evaluatedCodeRowNum).toString();
            String evaluatedName = CollUtil.get(row, evaluatedNameRowNum).toString();
            String evaluatorName = CollUtil.get(row, evaluatorNameRowNum).toString();
            String evaluatorCode = CollUtil.get(row, evaluatorCodeRowNum).toString();
            String userRelationName = CollUtil.get(row, 4).toString();
            Long evaluated = null;
            if (FormTypeEnum.ORG.getValue().equals(formType)) {
                OrgEntity orgEntity = getOrgByName(evaluatedName);
                if (Objects.isNull(orgEntity)) {
                    stringBuilder.append(evaluatedName).append("-").append(evaluatorName).append(",");
                    continue;
                } else {
                    evaluated = orgEntity.getId();
                }
            } else if (FormTypeEnum.PERSON.getValue().equals(formType)) {
                //todx-lx 未考虑重名情况
                UserEntity userEntity = userService.query().eq("code", evaluatedCode).one();
                if (Objects.isNull(userEntity)) {
                    stringBuilder.append(evaluatedName).append("-").append(evaluatorName).append(",");
                    continue;
                }
                evaluated = userEntity.getId();
            }
            RelationshipEntity relationshipEntity = new RelationshipEntity();
            relationshipEntity.setEvaluated(evaluated);
            relationshipEntity.setFormKey(formKey);
            relationshipEntity.setType(formType);
            if (FormTypeEnum.ORG.getValue().equals(formType)) {
                List<UserEntity> userEntityList = userService.query().eq("name", evaluatorName).isNotNull("yht_id").list();
                if (CollUtil.isEmpty(userEntityList)) {
                    stringBuilder.append(evaluatedName).append("-").append(evaluatorName).append(",");
                    continue;
                } else if (userEntityList.size() > 1) {
                    Object orgName = CollUtil.get(row, 2);
                    if (Objects.isNull(orgName)) {
                        stringBuilder.append(evaluatedName).append("-").append(evaluatorName).append("（名字重复，请设置部门）,");
                        continue;
                    }
                    OrgEntity orgEntity = getOrgByName(orgName.toString());
                    if (Objects.isNull(orgEntity)) {
                        stringBuilder.append(evaluatedName).append("-").append(evaluatorName).append("（名字重复，部门未找到）,");
                        continue;
                    }
                    UserEntity user = getUserByNameAndOrgId(evaluatorName, orgEntity.getId());
                    if (Objects.isNull(user)) {
                        stringBuilder.append(evaluatedName).append("-").append(evaluatorName).append("（名字重复，用户未找到）,");
                    }
                    relationshipEntity.setEvaluator(user.getId());
                } else {
                    relationshipEntity.setEvaluator(userEntityList.get(0).getId());
                }
            } else if (FormTypeEnum.PERSON.getValue().equals(formType)) {
                UserEntity userEntity = userService.query().eq("code", evaluatorCode).one();
                if (Objects.isNull(userEntity)) {
                    stringBuilder.append(evaluatedName).append("-").append(evaluatorName).append("（名字重复，评价人用户未找到）,");
                }
                relationshipEntity.setEvaluator(userEntity.getId());
                FormUserRelationEntity formUserRelationEntity = formUserRelationService.query().eq("name", userRelationName).one();
                if (Objects.isNull(formUserRelationEntity)) {
                    stringBuilder.append(evaluatedName).append("-").append(evaluatorName).append("-").append(userRelationName).append(":该关系未配置");
                    continue;
                }
                relationshipEntity.setUserRelationId(formUserRelationEntity.getId());
            }
            relationshipEntityList.add(relationshipEntity);
        }
        if (CollUtil.isNotEmpty(relationshipEntityList)) {
            QueryWrapper<RelationshipEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("form_key", formKey);
            relationshipService.remove(queryWrapper);
            relationshipService.saveBatch(relationshipEntityList);
        }
        if (stringBuilder.length() > 0) {
            return "以下数据导入失败：\n" + stringBuilder;
        }
        return "导入成功";
    }

    private UserEntity getUserByNameAndOrgId(String name, Long orgId) {
        Object userObj = redisUtil.get(String.format(IMPORT_PERSON_KEY, name, orgId));
        if (Objects.isNull(userObj)) {
            UserEntity userEntity = userService.query().eq("name", name).eq("org_id", orgId).one();
            if (Objects.nonNull(userEntity)) {
                redisUtil.set(String.format(IMPORT_PERSON_KEY, name, orgId), JSON.toJSONString(userEntity), EXPIRED_TIME);
            }
            return userEntity;
        } else {
            return JSON.parseObject(userObj.toString(), UserEntity.class);
        }
    }

    private OrgEntity getOrgByName(String orgName) {
        Object evaluatedObj = redisUtil.get(IMPORT_ORG_KEY + orgName);
        if (Objects.isNull(evaluatedObj)) {
            OrgEntity orgEntity = orgService.query().eq("name", orgName).one();
            if (Objects.nonNull(orgEntity)) {
                redisUtil.set(IMPORT_ORG_KEY + orgName, JSON.toJSONString(orgEntity), EXPIRED_TIME);
            }
            return orgEntity;
        } else {
            return JSON.parseObject(evaluatedObj.toString(), OrgEntity.class);
        }
    }

    public void export(String formKey, Integer type, HttpServletResponse response) {
        QueryWrapper<RelationshipEntity> relationshipEntityQueryWrapper = new QueryWrapper<>();
        relationshipEntityQueryWrapper.eq("form_key", formKey);
        List<RelationshipEntity> relationshipEntityList = relationshipService.queryAggregateData(relationshipEntityQueryWrapper);
        List<RelationshipExportVO> voList = BeanUtil.copyToList(relationshipEntityList, RelationshipExportVO.class);
        if (FormTypeEnum.PERSON.getValue().equals(type)) {
            for (RelationshipExportVO vo : voList) {
                if (Objects.nonNull(vo.getEvaluated())) {
                    vo.setEvaluatedCode(userService.getById(vo.getEvaluated()).getCode());
                }
                if (Objects.nonNull(vo.getEvaluator())) {
                    vo.setEvaluatorCode(userService.getById(vo.getEvaluator()).getCode());
                }
            }
            List<FormUserRelationEntity> formUserRelationEntities = formUserRelationService.query().eq("form_key", formKey).list();
            Map<Long, String> userRelationMap = formUserRelationEntities.stream().collect(Collectors.toMap(FormUserRelationEntity::getId, FormUserRelationEntity::getName));
            for (RelationshipExportVO relationship : voList) {
                relationship.setUserRelationName(userRelationMap.get(relationship.getUserRelationId()));
            }
        }
        Assert.notEmpty(relationshipEntityList, "还没有配置评价关系");
        String fileName = "评价关系_" + formKey + System.currentTimeMillis() + ".xls";
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
        try (OutputStream outputStream = response.getOutputStream()) {
            if (FormTypeEnum.ORG.getValue().equals(type)) {
                EasyExcel.write(outputStream, RelationshipEntity.class).sheet().doWrite(relationshipEntityList);
            } else if (FormTypeEnum.PERSON.getValue().equals(type)) {
                EasyExcel.write(outputStream, RelationshipExportVO.class).sheet().doWrite(voList);
            }
        } catch (IOException e) {
            log.error("导出评价关系数据失败,formKey：{}", formKey, e);
            throw new RuntimeException(e);
        }
    }
}
